/*!
基于rust和sciter的redis桌面客户端工具
*/
// 关闭window下的黑窗口
// #![windows_subsystem = "windows"]
mod events;

#[cfg(windows)]
use std::os::windows::process::CommandExt;

mod redis_helper;
mod sqlite;
mod windows;

#[macro_use]
extern crate sciter;
#[macro_use]
extern crate lazy_static;

use std::io::{Read, Write};
use std::path::PathBuf;
use std::result::Result::Ok;
lazy_static! {
    /// 定义全局文件资源
    pub static ref RESOURCE: &'static [u8] = include_bytes!("resource.rc");
}
/// 主程序入口
fn main() {
    // 设置配置sciter
    sciter::set_options(sciter::RuntimeOptions::ScriptFeatures(
        sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_SYSINFO as u8
            | sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_FILE_IO as u8
            | sciter::SCRIPT_RUNTIME_FEATURES::ALLOW_SOCKET_IO as u8,
    ))
    .unwrap();
    // 开发模式下打开sciter调试
    if cfg!(debug_assertions) {
        sciter::set_options(sciter::RuntimeOptions::DebugMode(true)).unwrap();
    }
    // 写pid文件
    if let Err(_) = write_pid() {
        std::process::exit(2);
    }

    // 启动tray
    windows::service(*RESOURCE);
}
/// 写pid方法
fn write_pid() -> std::io::Result<()> {
    let temp_dir = std::env::temp_dir();
    let pid_file = std::path::Path::join(temp_dir.as_path(), "bs.pid");
    fn save(path: &PathBuf) -> std::io::Result<()> {
        let mut file = std::fs::File::create(&path)?;
        let pid = std::process::id();
        file.write(format!("{}", pid).as_bytes())?;
        Ok(())
    }
    match std::fs::File::open(&pid_file) {
        Ok(mut file) => {
            let mut buf = String::new();
            file.read_to_string(&mut buf)?;
            if check_is_running(buf) == true {
                std::process::exit(0);
            }
            save(&pid_file)?
        }
        Err(_) => save(&pid_file)?,
    };
    Ok(())
}

#[cfg(windows)]
/// 校验软件是否已经在运行方法
fn check_is_running(pid: String) -> bool {
    let cmd_str = format!("tasklist /v | findstr /i {}", pid);
    if let Ok(res) = std::process::Command::new("cmd")
        .creation_flags(0x08000000)
        .arg("/c")
        .arg(cmd_str)
        .output()
    {
        let str = String::from_utf8(res.stdout).unwrap_or(String::new());
        println!("{}", str);
        if str.len() == 0 || !str.contains("bs.exe") {
            return false;
        }
        true
    } else {
        false
    }
}

#[cfg(not(windows))]
///  校验软件是否已经在运行方法
fn check_is_running(pid: String) -> bool {
    unsafe {
        let res = libc::kill(pid.parse().unwrap_or(0000), 0);
        return res == 0;
    }
}
